package com.bjf.commqry.util;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.log4j.Logger;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.bjf.common.ComCons;
import com.bjf.common.Module;
import com.bjf.common.Rescode;
import com.bjf.common.SystemDProperty;
import com.bjf.commqry.bean.CommonQueryBean;
import com.bjf.commqry.common.CommonQueryConstants;
import com.bjf.exception.BJFException;

public class CommonQueryUtil {
	/** this variable is to obtain a necessary recording log */
	private static Logger logger = Logger.getLogger(ComCons.SYSTEM_STRAT_UP_LOG);

	/** memeber variable: common query map. */
	private static HashMap configMap = new HashMap(2);

	/** memeber variable: common query query map. */
	private static HashMap metaMap = new HashMap(2);

	private static ServletContext servletContext = null;

	public static void init(String[] confFiles,ServletContext context) throws BJFException{
		servletContext = context;
		init(confFiles);
	}
	
	public static void init(String[] confFiles) throws BJFException {
		// initize Meta Files
		initMeta(confFiles);
		// initize Config Files
		initConfFile();
	}
	
	/**
	 * initize meta config files
	 *
	 * @param confFiles
	 * @throws BJFException
	 */
	private static void initMeta(String[] confFiles) throws BJFException {
		int num = confFiles.length;
		File metaFile = null;
		Document document;
		Element element;
		List list, l;
		Attribute id, path;
		try {
			SAXReader saxReader = new SAXReader();
			for (int i = 0; i < num; i++) {
				if (SystemDProperty.isProductionMode()) {
					document = saxReader.read(servletContext.getResourceAsStream(confFiles[i]));
				} else{
					metaFile = new File(ComCons.rootPath + File.separator + confFiles[i]);
					document = saxReader.read(metaFile);
					if (!metaFile.exists()) {
						throw new BJFException(Module.SYSTEM_MODULE,
								Rescode.COMMONQUERYUTIL_INIT_META_FILE_NOEXISTS,
								"Meta File :" + confFiles[i] + " no exists");
					}
				}

				list = document.selectNodes("//" + CommonQueryConstants.META_ROOT + "/" + CommonQueryConstants.META_QUERY);
				for (int j = 0; j < list.size(); j++) {
					element = (Element) list.get(j);
					l = element.selectNodes("@" + CommonQueryConstants.META_QUERY_ID);
					if (l.size() != 1) {
						throw new BJFException(Module.SYSTEM_MODULE, Rescode.COMMONQUERYUTIL_INIT_META_PARSE_QUERY_ID_ERROR, "Query.id error");
					}
					id = (Attribute) l.get(0);
					l = element.selectNodes("@" + CommonQueryConstants.META_QUERY_PATH);
					if (l.size() != 1) {
						throw new BJFException(Module.SYSTEM_MODULE, Rescode.COMMONQUERYUTIL_INIT_META_PARSE_QUERY_PATH_ERROR, "Query.path error");
					}
					path = (Attribute) l.get(0);
					// key=Query Id, value=Query Path
					metaMap.put(id.getValue(), path.getValue());
				}

			}
		}catch (BJFException appEx) {
			throw appEx;
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new BJFException(Module.SYSTEM_MODULE, Rescode.COMMONQUERYUTIL_INIT_META_PARSE_FILE_ERROR, ex);
		}
	}
	
	
	/**
	 * initize common query config file
	 *
	 * @throws ComException
	 */
	private static void initConfFile() throws BJFException {
		try {
			CommonQueryParser parser = new CommonQueryParser();
			Iterator it = metaMap.keySet().iterator();
			String id, path;
			File confFile;
			CommonQueryBean bean;
			while (it.hasNext()) {
				id = (String) it.next();
				path = (String) metaMap.get(id);

				if (logger.isDebugEnabled()) {
					logger.info(ComCons.traceInfo("Paser Config File:" + path + " Begin"));
				}

				if( SystemDProperty.isProductionMode() ){
					bean = parser.parse(servletContext.getResourceAsStream(path));
				}else{
					confFile = new File(ComCons.rootPath + File.separator + path);
					if (!confFile.exists()) {
						throw new BJFException(Module.SYSTEM_MODULE, Rescode.COMMONQUERYUTIL_INIT_CONFIG_FILE_NOEXISTS, "Common Query Config File :" + path
								+ " no exists");
					}
					bean = parser.parse(confFile);
				}
				bean.setTxnId(id);
				configMap.put(id, bean);
			}
		} catch (BJFException appEx) {
			throw appEx;
		} catch (Exception ex) {
			throw new BJFException(Module.SYSTEM_MODULE, Rescode.COMMONQUERYUTIL_INIT_META_PARSE_FILE_ERROR, ex);
		}
	}
	
	/**
	 * get Query
	 * @param txnId
	 * @return
	 * @throws BJFException
	 */
	public static CommonQueryBean getQuery(String txnId) throws BJFException {
		return (CommonQueryBean)configMap.get(txnId);
	}
}
